#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/time.h>

#include <concurrency/PosixThreadFactory.h> 
#include <concurrency/ThreadManager.h>
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <server/TThreadPoolServer.h>
#include <server/TThreadedServer.h>
#include <server/TNonblockingServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>


#include "Indexer.h"
#include "Searcher.h"
#include "Reader.h"
#include "Md5Searcher.h"
#include "indexService.h"


#define WORDS_DICT "/home/vv/codes/chSeg/Seg-new/chwords.txt"
#define T2S "/home/vv/codes/chSeg/Seg-new/t2s.txt"
#define STOPWORD "/home/vv/codes/chSeg/Seg-new/stopwords.txt"

using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using namespace ::apache::thrift::concurrency;
using boost::shared_ptr;

using namespace std;


CIndexer<propertyEntry> *indexer;
CSearcher<propertyEntry> *searcher;


class indexServiceHandler : virtual public indexServiceIf {
 public:
  indexServiceHandler() {
    // Your initialization goes here
      char path[]="";
      indexer = new CIndexer<propertyEntry> (path,
					     100000);//todo hash_size
      indexer->setSegment(WORDS_DICT, T2S, STOPWORD);
      
      Reader r;
      char file_name[] = "/home/vv/codes/data/utsz_ftp/ftp.utsz.edu.cn.data";
      r.loadFile(file_name);
      fileitem item;
      while (r.readNextItem(item) > 0) {
	  char *content = (char*) malloc(strlen(item.name_with_format) + 1);
	  strcpy(content, item.name_with_format);
	  propertyEntry *pe = NULL;
	  try {
	      pe = new propertyEntry;
	  } catch (...) {
	      cout << "oom" << endl;
	      exit(0);
	  }
	  memset(pe, 0, sizeof(propertyEntry));
	  pe->time = item.pe.time;
	  pe->size = item.pe.size;
	  //strcpy(pe->md5, item.pe.md5);
	  pe->file_type = item.pe.file_type;
	  strcpy(pe->path, item.pe.path);
	  //cout<<"add:"<<content<<endl;
	  indexer->add(content, pe, IN_MEMORY);
      }
      searcher = new CSearcher<propertyEntry> (indexer);
      
  }

  void search(std::vector<Result> & _return, const std::string& key) {
      // Your implementation goes here
      searcher->search(key.c_str(), _return,IN_MEMORY);
      //  printf("search\n");
  }

};

int main(int argc, char **argv) {
  const int port = 19092;
  const int workerCount = 2;
  shared_ptr<indexServiceHandler> handler(new indexServiceHandler());
  shared_ptr<TProcessor> processor(new indexServiceProcessor(handler));
  shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
  shared_ptr<PosixThreadFactory> threadFactory(new PosixThreadFactory());
  threadManager->threadFactory(threadFactory);
  threadManager->start();
  TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager);

  //TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
  //server.serve();

  server.serve();

  delete indexer;
  delete searcher;
  /*
  int port = 9090;
  shared_ptr<indexServiceHandler> handler(new indexServiceHandler());
  shared_ptr<TProcessor> processor(new indexServiceProcessor(handler));
  shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
  server.serve();
  */
  return 0;
}

